﻿using System;
using System.Collections.Generic;

namespace geekcmd
{
	enum SortOrder
	{
		Time,
		Size,
		Name,
		Extension,
		Unsorted
	}

	class FileList
	{
		public static readonly string CurrentDirectory = ".";
		public static readonly string UpperDirectory = "..";

		string path;
		List<FileInfo> entries = new List<FileInfo>();
		int dirsCount;
		int filesCount;
		int longestName;
		ulong totalSize;

		#region Properties
		public string Path
		{
			get { return path; }
		}

		public List<FileInfo> Entries
		{
			get { return entries; }
		}

		public int DirectoriesCount
		{
			get { return dirsCount; }
		}

		public int FilesCount
		{
			get { return filesCount; }
		}

		public int LongestName
		{
			get { return longestName; }
		}

		public ulong TotalSize
		{
			get { return totalSize; }
		}
		#endregion

		public void Sort(SortOrder sortOrder)
		{
			switch (sortOrder)
			{
				case SortOrder.Time:
					entries.Sort(FileInfo.CompareByTime);
					break;
				case SortOrder.Size:
					entries.Sort(FileInfo.CompareBySize);
					break;
				case SortOrder.Name:
					entries.Sort(FileInfo.CompareByName);
					break;
				case SortOrder.Extension:
					entries.Sort(FileInfo.CompareByExtension);
					break;
			}
		}

		public static FileList Walk(string path)
		{
			var data = new Win32Native.WIN32_FIND_DATA();
			IntPtr handle = Win32Native.FindFirstFile(System.IO.Path.Combine(path, "*"), data);
			if (handle != (IntPtr)(-1))
			{
				var fileList = new FileList();
				fileList.path = path;
				do
				{
					if (data.cFileName != CurrentDirectory)
					{
						FileInfo fileInfo = new FileInfo(data);

						if (fileInfo.Directory)
						{
							if (fileInfo.Name != UpperDirectory)
							{
								++fileList.dirsCount;
							}
						}
						else
						{
							++fileList.filesCount;
						}

						fileList.longestName = System.Math.Max(fileList.longestName, fileInfo.Name.Length);

						fileList.totalSize += fileInfo.Size;

						fileList.entries.Add(fileInfo);
					}
				}
				while (Win32Native.FindNextFile(handle, data));
				Win32Native.FindClose(handle);
				return fileList;
			}
			return null;
		}
	}
}
